{
 "metadata": {
  "signature": "sha256:d54d1b3271740b613971d855a93e81cf12fb5d43a3274ccc7ec49f55a65ff903"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Scripting Mayavi 2: filters\n",
      "======================================================================\n",
      "\n",
      "Introduction\n",
      "------------\n",
      "\n",
      "Well, until now, examples above are quite simple: scalars or vectors\n",
      "data are presented in the \"vaccum\", i.e. there is not object or material\n",
      "or whatsoever.\n",
      "\n",
      "In others words, how can one display some object, say a metallic\n",
      "parallellepiped, for example, in a scalars or vectors field ?\n",
      "\n",
      "The first filter you will be presented here deals with this problem.\n",
      "\n",
      "ExtractUnstructuredGrid filter\n",
      "------------------------------\n",
      "\n",
      "For this example, we suppose several hypotheses:\n",
      "\n",
      "`*\u00a0the\u00a0mesh\u00a0of\u00a0the\u00a0volume\u00a0data\u00a0is\u00a0made\u00a0of\u00a076x60x72\u00a0cubic\u00a0cells\u00a0(8\u00a0vertices);\u00a0thus,\u00a0the\u00a0VTK\u00a0object\u00a0cell\u00a0used\u00a0for\u00a0the\u00a0\"vaccum\"\u00a0is\u00a0called\u00a0VTK_HEXAHEDRON\u00a0(#12).\u00a0Cell\u00a0ids\u00a0begins\u00a0at\u00a00\u00a0and\u00a0ends\u00a0at\u00a0#342880.`\n",
      "\n",
      "`*\u00a0a\u00a0metallic\u00a0parallellepiped\u00a0is\u00a0immersed\u00a0in\u00a0a\u00a0EM\u00a0field\u00a0spreading\u00a0over\u00a0the\u00a0whole\u00a0volume\u00a0data\u00a0;\u00a0this\u00a0object\u00a0is\u00a0made\u00a0of\u00a0faceted\u00a0cells\u00a0(4\u00a0vertices),\u00a0called\u00a0VTK_QUAD\u00a0(#9)\u00a0cells\u00a0in\u00a0VTK\u00a0denomination.\u00a0These\u00a0faceted\u00a0cells\u00a0are\u00a0used\u00a0here\u00a0because\u00a0of\u00a0the\u00a0null\u00a0EM\u00a0field\u00a0within\u00a0the\u00a0parallellepiped.\u00a0Cell\u00a0ids\u00a0begin\u00a0at\u00a0#342881\u00a0and\u00a0end\u00a0at\u00a0#345966.`\n",
      "\n",
      "`*\u00a0as\u00a0there\u00a0are\u00a0different\u00a0kinds\u00a0of\u00a0cells,\u00a0the\u00a0!UnstructuredGrid\u00a0data\u00a0set\u00a0must\u00a0be\u00a0used\u00a0(see\u00a0`[`http://www.vtk.org/pdf/file-formats.pdf`](http://www.vtk.org/pdf/file-formats.pdf)`\u00a0to\u00a0know\u00a0how\u00a0!UnstructuredGrid\u00a0files\u00a0must\u00a0be\u00a0written,\u00a0VTK\u00a0cells\u00a0syntax,\u00a0etc).`\n",
      "\n",
      "To display the metallic parallellepiped as a separate object from the\n",
      "vaccum, you have to extract the cells corresponding to this object.\n",
      "Thus, you will be able to display this object using the Surface module\n",
      "for example.\n",
      "\n",
      "First, import !ExtractUnstructuredGrid filter and Surface module, as\n",
      "usual:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from enthought.mayavi.modules.surface import Surface\n",
      "\n",
      "from enthought.mayavi.filters.extract_unstructured_grid import ExtractUnstructuredGrid"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "then"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "### for the metallic parallellepiped\n",
      "script.engine.current_object = src  # current object must be set to the source\n",
      "eug1 = ExtractUnstructuredGrid()\n",
      "script.add_filter(eug1)\n",
      "eug1.filter.cell_clipping = True\n",
      "eug1.filter.cell_minimum = 342881\n",
      "eug1.filter.cell_maximum = 345966\n",
      "s = Surface()                       # the metallic is displayed using Surface module\n",
      "eug1.add_module(s)                  # the module must be added to the current filter\n",
      "s.actor.mapper.scalar_visibility = False\n",
      "s.actor.property.color = (0.509804, 0.5098040, 0.5490196) # grey color for the metallic parallellepiped\n",
      "\n",
      "### we need also extract the required cells for and only for the vaccum\n",
      "script.engine.current_object = src  # current object must be set to the source\n",
      "eug2 = ExtractUnstructuredGrid()\n",
      "script.add_filter(eug2)\n",
      "eug2.filter.cell_clipping = True\n",
      "eug2.filter.cell_minimum = 0\n",
      "eug2.filter.cell_maximum = 342880\n",
      "\n",
      "### here, we can display the EM field using ScalarCutPlane/VectorCutPlane,\n",
      "### Surface, Vectors modules as usual\n",
      ".../..."
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "This should look like this:\n",
      "\n",
      "![](files/attachments/MayaVi_ScriptingMayavi2_Filters/filter_eug1.png\n",
      "\n",
      "For this first example, there was only one object, and it was faceted.\n",
      "\n",
      "Now, say we have a second object, not metallic but dielectric (so the EM\n",
      "field within it should not be null). Thus we have to use some 3D cells,\n",
      "as VTK\\_HEXAHEDRON cells (cell ids go from \\#345967 to \\#349094). We\n",
      "also want to display the field on the surface on the metallic object\n",
      "*and* in the dielectric object."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "### for the metallic parallellepiped\n",
      "script.engine.current_object = src\n",
      "eug1 = ExtractUnstructuredGrid()\n",
      "script.add_filter(eug1)\n",
      "eug1.filter.cell_clipping = True\n",
      "eug1.filter.cell_minimum = 342881\n",
      "eug1.filter.cell_maximum = 345966\n",
      "s = Surface()\n",
      "eug1.add_module(s)\n",
      "s.actor.mapper.scalar_visibility = True # scalar field on the surface\n",
      "\n",
      "### for the dielectric parallellepiped\n",
      "script.engine.current_object = src\n",
      "eug2 = ExtractUnstructuredGrid()\n",
      "script.add_filter(eug2)\n",
      "eug2.filter.cell_clipping = True\n",
      "eug2.filter.cell_minimum = 345967\n",
      "eug2.filter.cell_maximum = 349094\n",
      "s = Surface()\n",
      "eug2.add_module(s)\n",
      "s.actor.mapper.scalar_visibility = True # scalar field set to on\n",
      "s.enable_contours = True                # in the volume\n",
      "\n",
      "### we need also extract the required cells for and only for the vaccum\n",
      "script.engine.current_object = src  # current object must be set to the source\n",
      "eug3 = ExtractUnstructuredGrid()\n",
      "script.add_filter(eug3)\n",
      "eug3.filter.cell_clipping = True\n",
      "eug3.filter.cell_minimum = 0\n",
      "eug3.filter.cell_maximum = 342880\n",
      "\n",
      ".../..."
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "This should render this:\n",
      "\n",
      "![](files/attachments/MayaVi_ScriptingMayavi2_Filters/filter_eug2.png\n",
      "\n",
      "ExtractGrid filter\n",
      "------------------\n",
      "\n",
      "Using !ExtractGrid filter is easier, because it works (only) on\n",
      "structured grids: you only have to set min/max values for x, y, z\n",
      "coordinates. Thus, you can cut a subvolume of your data. You can also\n",
      "apply a ratio on each coordinates, to decrease the cells number.\n",
      "\n",
      "Import, as usual, the required modules and/or filter:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from enthought.mayavi.modules.surface import Surface\n",
      "\n",
      "from enthought.mayavi.filters.extract_grid import ExtractGrid"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "then you can set filter's limits as:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "eg = ExtractGrid()\n",
      "script.add_filter(eg)\n",
      "eg.x_min, eg.x_max = 10, 40\n",
      "eg.y_min, eg.y_max = 10, 40\n",
      "eg.z_min, eg.z_max = 10, 40\n",
      "\n",
      "# eg.x_ratio = 2\n",
      "# eg.y_ratio = 2\n",
      "# eg.z_ratio = 2\n",
      "\n",
      "# same example using Surface module\n",
      "s = Surface()\n",
      "s.enable_contours = True\n",
      "s.contour.auto_contours = True\n",
      "s.contour.number_of_contours = 10\n",
      "s.actor.property.opacity = 0.2\n",
      "script.add_module(s)\n",
      "s.contour.minimum_contour = 0\n",
      "s.contour.maximum_contour = 1\n",
      "s.module_manager.scalar_lut_manager.data_range = [0, 1]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![](files/attachments/MayaVi_ScriptingMayavi2_Filters/filter_eg.png\n",
      "\n",
      "Threshold filter\n",
      "----------------\n",
      "\n",
      "Using this filter, you can consider scalars values contained in a\n",
      "specific range.\n",
      "\n",
      "Suppose that your scalars data spread from 0 to 1, but you are only\n",
      "interested by the values in the range [0.4, 0.6] and you want to play\n",
      "with the slidebar of the !IsoSurface module within this range, around\n",
      "0.5. By default, min & max values of the slidebar will be set to 0 & 1,\n",
      "because of your data range:\n",
      "\n",
      "![](files/attachments/MayaVi_ScriptingMayavi2_Filters/filter_thrld1.png\n",
      "\n",
      "To play more accurately with the slidebar of the !IsoSurface module, you\n",
      "have to set min & max values to the required values, i.e. 0.4 & 0.6.\n",
      "Thus, if you want to see your scalars data around 0.5, you can set the\n",
      "slidebar from 0.4 to 0.6 more easily than in the case where slidebar\n",
      "goes form 0 to 1.\n",
      "\n",
      "The Threshold filter can help you to do this.\n",
      "\n",
      "Begin to import the module and the filter first:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from enthought.mayavi.modules.iso_surface import IsoSurface\n",
      "\n",
      "from enthought.mayavi.filters.threshold import Threshold"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "then, set the threshold values:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "thh = Threshold()\n",
      "script.add_filter(thh)\n",
      "thh.lower_threshold = 0.4\n",
      "thh.upper_threshold = 0.6\n",
      "isosurf = IsoSurface()\n",
      "thh.add_module(isosurf)\n",
      "isosurf.contour.contours = [0.5]\n",
      "isosurf.compute_normals = True\n",
      "isosurf.actor.property.opacity = 0.2\n",
      "isosurf.module_manager.scalar_lut_manager.data_range = [0, 1]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "and you're done !\n",
      "\n",
      "This should look like this:\n",
      "\n",
      "![](files/attachments/MayaVi_ScriptingMayavi2_Filters/filter_thrld2.png\n",
      "\n",
      "You can notice on the two previous figures that the Threshold module\n",
      "approximates bounds to the nearest values (there are not strictly equal\n",
      "to 0.4 & 0.6).\n",
      "\n",
      "PointToCellData filter\n",
      "----------------------\n",
      "\n",
      "Generally, data are interpolated between each point. Thus, they look\n",
      "like nicer.\n",
      "\n",
      "But maybe in some case, you don't want them to be interpolated, and see\n",
      "the data \"as they are\": they are not displayed as points, but as cells.\n",
      "In this case, you can use the !PointToCellData filter.\n",
      "\n",
      "Let's see again the example using the !ScalarCutPlane module, and import\n",
      "the !PointToCellData filter:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from enthought.mayavi.modules.scalar_cut_plane import ScalarCutPlane\n",
      "\n",
      "from enthought.mayavi.filters.point_to_cell_data import PointToCellData"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "then add the !ScalarCutPlane module \"above\" the !PointToCellData filter,\n",
      "as usual:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "ptocd = PointToCellData()\n",
      "script.add_filter(ptocd)\n",
      "scp = ScalarCutPlane()\n",
      "ptocd.add_module(scp)\n",
      "scp.implicit_plane.normal = (1, 0, 0)\n",
      "scp.implicit_plane.origin = (10, 25, 25)\n",
      "scp.implicit_plane.widget.enabled = False\n",
      "scp.actor.property.diffuse = 0.0\n",
      "scp.actor.property.ambient = 1.0\n",
      "scp.actor.property.opacity = 1.0\n",
      "scp.module_manager.scalar_lut_manager.data_range = [0, 1]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": []
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Thus, you can see your data on each cell and not as points (compare to the first figure showing the use of the !ScalarCutPlane module):\n",
      "\n",
      "![](files/attachments/MayaVi_ScriptingMayavi2_Filters/filter_p2c.png)\n",
      "\n",
      "## WarpScalar filter\n",
      "\n",
      "You can use the !WarpScalar filter to warp a 2D surface for example. See [:Cookbook/MayaVi/Examples: Example using mlab (surf_regular_mlab.py)].\n",
      "\n",
      "## TransformData filter\n"
     ]
    }
   ],
   "metadata": {}
  }
 ]
}